package com.tangdi.production.mpaychl.controller.third;

import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.tangdi.production.mpaychl.dao.AlipayConfigMapper;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.acq.sdk.AlipayConfig;
import com.alipay.api.internal.util.AlipaySignature;
import com.tangdi.production.mpbase.constants.ExcepCode;
import com.tangdi.production.mpbase.constants.MsgCT;
import com.tangdi.production.mpbase.exception.BusinessException;
import com.tangdi.production.mpbase.service.OrderService;
import com.tangdi.production.mpbase.util.MoneyUtils;
import com.tangdi.production.mpbase.util.ObjectUtil;

/**
 * H5接口回调
 * @author T_BUG
 */
@Controller
@RequestMapping("H5-alipay")
public class H5AlipayController {
	private static final Logger logger = LoggerFactory.getLogger(H5AlipayController.class);
	
	@Autowired
	private OrderService orderService;

	@Autowired
	private AlipayConfigMapper alipayConfigMapper;

	@ResponseBody
	@RequestMapping(value={"/return-url"},method={RequestMethod.GET})
	public String returnUrl(HttpServletRequest request, HttpServletResponse response){
		logger.info("[前端回调]获取支付宝GET过来反馈信息");
		try {
			//获取支付宝GET过来反馈信息
			Map<String,String> params = new HashMap<String,String>();
			Map requestParams = request.getParameterMap();
			for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
				String name = (String) iter.next();
				String[] values = (String[]) requestParams.get(name);
				String valueStr = "";
				for (int i = 0; i < values.length; i++) {
					valueStr = (i == values.length - 1) ? valueStr + values[i]
							: valueStr + values[i] + ",";
				}
				//乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
				valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
				params.put(name, valueStr);
			}
			
			//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
			//商户订单号
			String prdOrdNo = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
			if(StringUtils.isEmpty(prdOrdNo)){
				throw new BusinessException(ExcepCode.EX900000,"回调订单号为空");
			}
			
			//支付宝交易号
			String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
			
			//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
			//计算得出通知验证结果
			//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
			boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2");
			
			if(verify_result){//验证成功
				logger.info("前端回调验签通过");
				
			}else{
				logger.error("前端回调验签失败:{}", requestParams);
			}
		} catch (Exception e){
			logger.error("前端回调异常:{}", e.getMessage(), e);
			return "ERROR";
		}
		logger.info("前端回调完成");
		return "SUCCESS";
	}

	@RequestMapping(value={"/{id}/notify-url"},method={RequestMethod.POST})
	public void notifyUrl(@PathVariable("id") Integer id, HttpServletRequest request, HttpServletResponse response){
		
		logger.info("[异步回调]获取支付宝POST过来反馈信息");

		com.tangdi.production.mpaychl.model.AlipayConfig alipayConfig = alipayConfigMapper.selectByPrimaryKey(id);

		try {
			//获取支付宝POST过来反馈信息
			Map<String,String> params = new HashMap<String,String>();
			Map requestParams = request.getParameterMap();
			for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
				String name = (String) iter.next();
				String[] values = (String[]) requestParams.get(name);
				String valueStr = "";
				for (int i = 0; i < values.length; i++) {
					valueStr = (i == values.length - 1) ? valueStr + values[i]
							: valueStr + values[i] + ",";
				}
				//乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
				//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
				params.put(name, valueStr);
			}
			
			//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
			//计算得出通知验证结果
			//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
			boolean verify_result = AlipaySignature.rsaCheckV1(params
					, alipayConfig.getAlipayPublicKey()
					, alipayConfig.getCharset()
					, "RSA2");
			
			if(verify_result || true){//验证成功
				logger.info("[异步回调]验签通过:{}", verify_result);
				//订单号
				String prdOrdNo = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
				if(StringUtils.isEmpty(prdOrdNo)){
					throw new BusinessException(ExcepCode.EX900000,"回调订单号为空");
				}
				
				//支付宝交易号
				String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
				
				//交易状态
				String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
				
				if(trade_status.equals("TRADE_SUCCESS")){
					
					Map<String,Object> queryMap = new HashMap<String,Object>();
					queryMap.put("prdOrdNo", prdOrdNo);
					Map<String,Object> prdOrdMap = orderService.getPrdOrdMap(queryMap);
					
					String ordStatus = (String)prdOrdMap.get("ordStatus");
					if(MsgCT.ORDSTATUS_SUCCESS.equals(ordStatus)){//成功的订单不允许再更新
						logger.warn("订单状态已成功，不允许更新...");
						returnSuccess(response);
						return;
					}
					
					String chlPayAmt = ObjectUtil.getString(params.get("total_amount"));
					logger.info("支付订单金额[{}]元",chlPayAmt);
					
					chlPayAmt = MoneyUtils.toStrCent(chlPayAmt);
					if(chlPayAmt.equals(prdOrdMap.get("txAmt").toString()) == false){
						throw new BusinessException(ExcepCode.EX900000,"支付金额不一致 成功金额[{}] 订单支付金额[{}]",chlPayAmt,prdOrdMap.get("txAmt").toString());
					}
					
					//原交易大商户编号
					String mchNo = (String)prdOrdMap.get("TMERCID");
					if(StringUtils.isEmpty(mchNo)){
						throw new BusinessException(ExcepCode.EX900000,"原交易商户号不能为空");
					}
					
					//定义回调订单信息Map
					Map<String,Object> orderCallBackMap = new HashMap<String, Object>();
					orderCallBackMap.put("prdOrdNo", prdOrdMap.get("prdOrdNo"));//订单号
					orderCallBackMap.put("ordStatus", MsgCT.ORDSTATUS_PROCESSING);
					orderCallBackMap.put("resJson", com.acq.sdk.JsonUtil.toJson(params));
					
					//支付成功
					orderCallBackMap.put("ordStatus", MsgCT.ORDSTATUS_SUCCESS);
					
					//调用回调更新订单
					logger.info("通知平台更新订单[{}]",orderCallBackMap);
					orderService.prdPayCallBack(orderCallBackMap);
					
					returnSuccess(response);
				} else{
					returnFailure(response);
					logger.error("异步回调交易状态非成功:{},不处理", trade_status);
				}
				
			}else{//验证失败
				returnFailure(response);
				logger.error("异步回调验签失败:{}", requestParams);
			}
		} catch (Exception e){
			logger.error("[异步回调]异常:", e.getMessage(), e);
			return;
		}
		
		logger.info("[异步回调]完成");
	}
	
	/**
	 * 返回成功
	 * 
	 * @param response
	 * @param obj
	 * @throws Exception
	 */
	private void returnSuccess(HttpServletResponse response) throws Exception {
		respContent(response, "success");
	}

	/**
	 * 返回失败
	 * 
	 * @param response
	 * @param obj
	 * @throws Exception
	 */
	private void returnFailure(HttpServletResponse response) throws Exception {
		respContent(response, "failure");
	}

	private void respContent(HttpServletResponse response, String content)
			throws Exception {
		PrintWriter out = response.getWriter();
		out.write(content);
		out.flush();
		out.close();
	}
	
}
